package workers

import (
	"black_mamba/global"
	"fmt"
	"gitee.com/wengo/go-amazon"
	"gitee.com/wengo/go-mamba"
	"github.com/PuerkitoBio/goquery"
	"github.com/tidwall/gjson"
	"io/ioutil"
	"sync"
)

type CouponWorker struct {
	Worker
}

func NewCouponWorker() *CouponWorker {
	return &CouponWorker{
		Worker{
			Topic: "coupon",
		},
	}
}

func (d *CouponWorker) GetCouponThread(data map[string]interface{}) (ret interface{}) {

	amz := data["amz"].(*amazon.Amazon)
	asin := data["asin"].(string)
	sellerId := data["seller_id"].(string)
	zipcode := data["zipcode"].(string)
	email := data["email"].(string)

	// 打开listing
	d.sendLog(map[string]string{"status": "info", "email": email, "content": fmt.Sprintf("查看 %s listing", asin)})
	resp, document, err := amz.Navigate(fmt.Sprintf("/dp/%s/ref=sr_1_2?m=%s&sr=1-1", asin, sellerId))
	if err != nil {
		d.sendLog(map[string]string{"status": "error", "email": email, "content": err.Error()})
		return
	}

	resp, _, err = amz.GetCoupon(resp.String())

	if err != nil {
		d.sendLog(map[string]string{"status": "error", "email": email, "content": fmt.Sprintf("%s, 当前地址邮编 : %s", err.Error(), zipcode)})
	} else {
		d.sendLog(map[string]string{"status": "info", "email": email, "content": fmt.Sprintf("成功获取商家 %s 的 %s 折扣券, 结果为: %s", sellerId, asin, resp.String())})

		d.sendLog(map[string]string{"status": "info", "email": email, "content": "开始加入购物车"})
		resp, document, err = amz.AddCart(document, 1)

		if err != nil {
			d.sendLog(map[string]string{"status": "error", "email": email, "content": fmt.Sprintf("加入购物车失败, 原因: %s", err.Error())})
			return
		}

		if !amz.CheckAddCartSuccess(document) {
			d.sendLog(map[string]string{"status": "error", "email": email, "content": fmt.Sprintf("%s 加入购物车失败", asin)})
			return
		} else {
			d.sendLog(map[string]string{"status": "info", "email": email, "content": fmt.Sprintf("%s 加入购物车成功", asin)})
			//ret = map[string]string{
			//	"status": "success",
			//	"asin":   asin,
			//}
		}

	}

	return

	// 打开Listing
	/* 旧版本
	d.sendLog(map[string]string{"status": "info", "email": user.Emailaddress,  "content": fmt.Sprintf("查看 %s listing", asin)})
	_, document, err := amz.Navigate(fmt.Sprintf("/dp/%s/ref=sr_1_2?m=%s&sr=1-1", asin, sellerId))
	if err != nil {
		d.sendLog(map[string]string{"status": "error", "email": user.Emailaddress,  "content": err.Error()})
		return
	}

	html, _ := document.Html()
	ioutil.WriteFile(fmt.Sprintf("%s.html", asin), []byte(html), 0644)

	if !amz.CheckListingHasCart(document) {
		d.sendLog(map[string]string{"status": "error", "email": user.Emailaddress,  "content": fmt.Sprintf("%s 没有购物车按钮，不加购", asin)})
		return
	}

	// 加入购物车
	document, err = amz.AddCart(document, quantity)
	if err != nil {
		d.sendLog(map[string]string{"status": "error", "email": user.Emailaddress,  "content": fmt.Sprintf("%s 加入购物车失败", asin)})
		return
	}

	if !amz.CheckAddCartSuccess(document) {
		d.sendLog(map[string]string{"status": "error", "email": user.Emailaddress,  "content": fmt.Sprintf("%s 加入购物车失败", asin)})
		html, _ = document.Html()
		ioutil.WriteFile(fmt.Sprintf("%s-addcart.html", asin), []byte(html), 0644)
		return
	} else {
		d.sendLog(map[string]string{"status": "info", "email": user.Emailaddress,  "content": fmt.Sprintf("%s 加入购物车成功", asin)})
	}*/

}

func (d *CouponWorker) Execute(data map[string]interface{}) (ret interface{}) {
	/*
		   流程
		    1.访问首页
			2.新建收货地址，新建信用卡
			3.打开Listing
			4.加入购物车
			5.结账
			6.选择地址
			7.选择信用卡
			8.建立订单
	*/

	//defer func() {
	//	//可以打印错误信息
	//	//recover()
	//	//fmt.Println(recover())
	//
	//	//没有错就不要打印
	//	if err := recover(); err != nil { //产生了panic异常
	//		stackStr := string(debug.Stack())
	//		utils.WriteFile("error.log", fmt.Sprintf("%s\n%s\n", err, stackStr))
	//	}
	//}()

	var resp *mamba.Response
	var document *goquery.Document
	var err error
	var couponWg sync.WaitGroup

	website := gjson.Get(data["tasks"].(string), "list.0.website.value").String()
	website = "www.amazon.com"
	code := gjson.Get(data["tasks"].(string), "list.0.code.value").String()

	// 获取cookies
	d.sendLog(map[string]string{"status": "info", "content": "获取账户信息"})

	//user, err := global.BM_API.GetCookies("us")
	// 德国
	user, err := global.BM_API.GetGmailCookies(code, global.BM_CONFIG.Section("basic").Key("serialNumberCiphertext").Value())

	if err != nil {
		d.sendLog(map[string]string{"status": "error", "content": "获取用户信息失败"})
		return
	}

	d.sendLog(map[string]string{"status": "info", "email": user.Emailaddress, "content": fmt.Sprintf("邮箱地址 -> %s", user.Emailaddress)})
	d.sendLog(map[string]string{"status": "info", "email": user.Emailaddress, "content": fmt.Sprintf("用户密码 -> %s", user.Password)})
	d.sendLog(map[string]string{"status": "info", "email": user.Emailaddress, "content": fmt.Sprintf("%s", user.Cookies)})

	amz := amazon.NewAmazon(amazon.Settings{
		JA3:       "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0",
		UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
		BaseUri:   fmt.Sprintf("https://%s", website),
		//BaseUri:     "https://www.amazon.com",
		Header: nil,

		Cookies:     user.HttpCookies,
		Debug:       false,
		DebugLength: 0,
		//Proxy:       `http://192.168.31.29:8080`,
		//Proxy: `http://db75692e99a147a4a8505e40dce06a2b:@proxy.crawlera.com:8011/`,
		//Proxy: fmt.Sprintf("http://%s:%s@http-dynamic.xiaoxiangdaili.com:10030", global.BM_CONFIG.Section("proxy").Key("username").Value(), global.BM_CONFIG.Section("proxy").Key("password").Value()),
	})

	//isExecute := data["isExecute"].(*bool)
	var responsePath, responseUrl string

	var accountStatistic = make(map[string]map[string]interface{})
	accountStatistic[user.Emailaddress] = make(map[string]interface{})
	accountStatistic[user.Emailaddress] = map[string]interface{}{
		"zipCode": "",
		"address": "",
		"cc":      "",
		"success": []interface{}{},
		"orders":  []string{},
		"asins":   []string{},
	}

	continueExecute := true
	for continueExecute {
		//if !*isExecute { //是否继续执行
		//	return
		//}

		switch {
		case resp == nil: // 首页
			d.sendLog(map[string]string{"status": "info", "email": user.Emailaddress, "content": "打开首页"})
			switch code {
			case "de", "uk", "fr":
				resp, document, err = amz.Navigate("/cookieprefs")
			default:
				resp, document, err = amz.Navigate("/")
			}

			if err != nil {
				d.sendLog(map[string]string{"status": "info", "email": user.Emailaddress, "content": err.Error()})
				return
			}
		case responsePath == "/cookieprefs":
			resp, document, err = amz.AcceptAllCookies(document)
			if err != nil {
				resp = nil
				continue
			}
		case responsePath == "/":
			var postalCode string
			zipCode, _ := global.BM_API.GetZipCode(code, global.BM_CONFIG.Section("basic").Key("serialNumberCiphertext").Value())
			accountStatistic[user.Emailaddress]["zipCode"] = zipCode.ZipCode
			postalCode = zipCode.ZipCode
			postalCode = "10001"
			resp, err = amz.ChangeAddress(document, postalCode)
			//resp, err = amz.ChangeAddress(document, amazon.Choice(zipCode))
			if err != nil {
				d.sendLog(map[string]string{"status": "error", "email": user.Emailaddress, "content": err.Error()})
				return
			} else {
				if gjson.Get(resp.String(), "address.zipCode").String() == "" {
					d.sendLog(map[string]string{"status": "error", "email": user.Emailaddress, "content": fmt.Sprintf("%s -> 邮编无效, 换邮编", postalCode)})
					resp, document, err = amz.Navigate("/")
					continue
				} else {
					d.sendLog(map[string]string{"status": "info", "email": user.Emailaddress, "content": fmt.Sprintf("已把地址修改为: %s %s", gjson.Get(resp.String(), "address.city").String(), gjson.Get(resp.String(), "address.zipCode").String())})
					println(user.Cookies)
					continueExecute = false
				}
			}

		case responsePath == `/gp/delivery/ajax/address-change.html`: // 在任务页面做任务或者尝试登陆页面做任务
			taskList := gjson.Get(data["tasks"].(string), "list").Array()

			for _, task := range taskList {
				asin := gjson.Get(task.String(), "asin.value").String()
				sellerId := gjson.Get(task.String(), "seller_id.value").String()
				email := user.Emailaddress
				global.BM_POOL.Submit(d.Decorator(d.GetCouponThread, map[string]interface{}{
					"asin":      asin,
					"seller_id": sellerId,
					"email":     email,
					"zipcode":   accountStatistic[user.Emailaddress]["zipCode"],
					"amz":       amz,
				}, &couponWg, nil))
			}

			couponWg.Wait()
			continueExecute = false
		default:
			d.sendLog(map[string]string{"status": "error", "email": user.Emailaddress, "content": fmt.Sprintf("知内容, 退出, 当前页面: %s", responseUrl)})

			ioutil.WriteFile("unknown.html", resp.Body(), 0644)
			continueExecute = false
		}

		if resp != nil {
			responsePath = resp.RawResponse.Request.URL.Path
			responseUrl = resp.RawResponse.Request.URL.String()
		}
	}

	var statistic map[string]string
	//total := utils.ArrayCountValues(accountStatistic[user.Emailaddress]["success"].([]interface{}))
	//global.BM_EVENTBUS.Publish("deals:feedback", total)
	//
	//statisticFormat := fmt.Sprintf("\n 邮箱    : %s\t\n 邮编    : %s\n 收货地址: %s\n 信用卡号: %s\n asins:   %s\n 订单总数: %d\n 订单列表: %s\n===========================================",
	//	user.Emailaddress,
	//	accountStatistic[user.Emailaddress]["zipCode"],
	//	accountStatistic[user.Emailaddress]["address"],
	//	accountStatistic[user.Emailaddress]["cc"],
	//	strings.Join(utils.RemoveDuplicateStr(accountStatistic[user.Emailaddress]["asins"].([]string)), "\t"),
	//	len(accountStatistic[user.Emailaddress]["orders"].([]string)),
	//	strings.Join(accountStatistic[user.Emailaddress]["orders"].([]string), "\t"),
	//)
	//
	//statistic = map[string]string{"status": "info", "content": statisticFormat}

	return statistic
}
